#include <stdio.h>
#include <octopus.h>
 
sbit CS=P2^7;
sbit SK=P2^6;
sbit DI=P2^5;
sbit DO=P2^4;


#define CS(x) octopus_io_set_pin(octopus, PIN, x)
#define SK(x) octopus_io_set_pin(octopus, PIN, x)
#define DI(x) octopus_io_set_pin(octopus, PIN, x)
#define DO_OUT(x) octopus_io_set_pin(octopus, PIN, x)
#define DO_IN() octopus_io_set_pin(octopus, PIN, x)


// Write enable must precede all programming modes.
void Ewen(void) {
 unsigned char temp,InData;
 CS=0; 
 SK=0;
 CS=1;
 InData=0x98; // 10011XXXX
 for(temp=9;temp!=0;temp--) { // 9
  DI=InData&0x80;
  SK=1; SK=0;
  InData<<=1;
 }
 CS=0;
}

// Disables all programming instructions.
void Ewds(void) {
 unsigned char temp,InData;
 CS=0;
 SK=0;
 CS=1;
 InData=0x80; // 10000XXXX
 for(temp=9;temp!=0;temp--) { // 9
  DI=InData&0x80;
  SK=1; SK=0;
  InData<<=1;
 }
 CS=0;
}

// Reads data stored in memory, at specified address.
unsigned int Read(unsigned char address) {
 unsigned char temp;
 unsigned int result;
 Ewen();
 SK=0; DI=1; // 110 A5-A0
 CS=0; CS=1;
 SK=1; SK=0;   // 1
 address=address&0x3f 0x80;
 for(temp=8;temp!=0;temp--) { // 8
  DI=address&0x80;
  SK=1; SK=0;
  address<<=1;
 }
 DO=1;
 for(temp=16;temp!=0;temp--) { // 16
  SK=1;
  result=(result<<1) DO;
  SK=0;
 }
 CS=0;
 Ewds();
 return(result);
}

// Writes memory location An - A0.
void Write(unsigned char address,unsigned int InData) {
 unsigned char temp;
 Ewen();
 SK=0; DI=1; // 101 A5-A0
 CS=0; CS=1;
 SK=1; SK=0;   // 1
 address=address&0x3f 0x40;
 for(temp=8;temp!=0;temp--) { // 8
  DI=address&0x80;
  SK=1; SK=0;
  address<<=1;
 }
 for(temp=16;temp!=0;temp--) { // 16
  DI=InData&0x8000;
  SK=1; SK=0;
  InData<<=1;
 }
 CS=0; DO=1;
 CS=1; SK=1;
 while(DO==0) {   // busy test
  SK=0; SK=1;
 }
 SK=0; CS=0;
 Ewds();
}

/*
// Erase memory location An - A0.
void Erase(unsigned char address) {
 unsigned char temp;
 Ewen();
 SK=0; DI=1; // 111 A5-A0
 CS=0; CS=1;
 SK=1; SK=0;   // 1
 address =0xc0;
 for(temp=8;temp!=0;temp--) { // 8
  DI=address&0x80;
  SK=1; SK=0;
  address<<=1;
 }
 CS=0; DO=1;
 CS=1; SK=1;
 while(DO==0) {
  SK=0; SK=1;
 }
 SK=0; CS=0;
 Ewds();
}

// Erases all memory locations. Valid only at VCC = 4.5V to 5.5V.
void Eral(void) {
 unsigned char temp,InData;
 Ewen();
 CS=0;
 SK=0;
 CS=1;
 InData=0x90; // 10010XXXX
 for(temp=9;temp!=0;temp--) { // 9
  DI=InData&0x80;
  SK=1; SK=0;
  InData<<=1;
 }
 CS=0; DO=1;
 CS=1; SK=1;
 while(DO==0) {
  SK=0; SK=1;
 }
 SK=0; CS=0;
 Ewds();
}

// Writes all memory locations. Valid only at VCC = 4.5V to 5.5V.
void Wral(unsigned int InData) {
 unsigned char temp,address;
 Ewen();
 CS=0;
 SK=0;
 CS=1;
 address=0x88; // 10001XXXX
 for(temp=9;temp!=0;temp--) { // 9
  DI=address&0x80;
  SK=1; SK=0;
  address<<=1;
 }
 for(temp=16;temp!=0;temp--) { // 16
  DI=InData&0x8000;
  SK=1; SK=0;
  InData<<=1;
 }
 CS=0; DO=1;
 CS=1; SK=1;
 while(DO==0) {
  SK=0; SK=1;
 }
 SK=0; CS=0;
 Ewds();
}

*/




int main()
{

  struct octopus_context octopus;
   
  if(!octopus_init(&octopus))
    printf("%s\n",octopus.error_str);

  if(octopus_open(&octopus)<0){
  //if(octopus_open_serial(&octopus,"20081109")<0){
    printf("%s\n",octopus.error_str);
    exit(0);
  }
  
  int i;
  char desc[64];
  octopus_get_hwdesc(&octopus, desc);
  printf("Device: %s\n",desc);

#if 0  
  #define PIN 11
  if(octopus_io_init(&octopus, PIN)<0)
    printf("ERROR: %s\n",octopus.error_str);

  if(octopus_io_set_pin_direction_out(&octopus,PIN)<0)
    printf("ERROR: %s\n",octopus.error_str);
  
  for(;;){
    if(octopus_io_set_pin(&octopus, PIN, 1)<0)
      printf("ERROR: %s\n",octopus.error_str);
   
    sleep(1);

    if(octopus_io_set_pin(&octopus, PIN, 0)<0)
      printf("ERROR: %s\n",octopus.error_str);
   
    sleep(1);
  }  
#endif
  if(octopus_close(&octopus)<1)  
    printf("ERROR: %s\n",octopus.error_str);
  
  return 0;


}

